class CharCount{
    static WHOLE_ALPHABET_NUM = 26*2;
    static _a_char_code = this.chStr2code('a');
    static _A_char_code = this.chStr2code('A');

    ch2cnt: Array<number>;

    constructor(init_str: string){
        this.ch2cnt = new Array(CharCount.WHOLE_ALPHABET_NUM).fill(0);
        for (let i = 0; i < init_str.length; i++) {
            this.ch2cnt[this.getCharIndex(init_str[i])]++;
        }
    }

    static chStr2code(ch: string): number{
        return ch.charCodeAt(0);
    }

    getCharIndex(chStr: string): number{
        let chIdx = CharCount.chStr2code(chStr);
        if(chIdx >= CharCount._a_char_code)
            return chIdx - CharCount._a_char_code;
        else
            return chIdx - CharCount._A_char_code + 26;
    }

    static lessThan(a: CharCount, b: CharCount): boolean{
        for (let i = 0; i < CharCount.WHOLE_ALPHABET_NUM; i++) {
            if(a.ch2cnt[i] < b.ch2cnt[i])
                return true;
        }
        return false;
    }
}

function minWindow(s: string, t: string): string {
    const tCharCount = new CharCount(t);
    const sCharCount = new CharCount(s);
    if (CharCount.lessThan(sCharCount, tCharCount))
        return "";
    const tmpCharCount = new CharCount(s[0]);
    let lef = 0, rig = 0;
    let ret_lef = 0, ret_rig = s.length;
    while (rig < s.length) {
        if (CharCount.lessThan(tmpCharCount, tCharCount)) {
            rig++;
            if (rig < s.length)
                tmpCharCount.ch2cnt[tmpCharCount.getCharIndex(s[rig])]++;
        } else {
            if (rig - lef < ret_rig - ret_lef) {
                ret_lef = lef;
                ret_rig = rig;
            }
            tmpCharCount.ch2cnt[tmpCharCount.getCharIndex(s[lef])]--;
            lef++;
        }
    }
    return s.substring(ret_lef, ret_rig + 1);
};

const input_arr = [
    {s: "ADOBECODEBANC", t: "ABC"},
    {s: "a", t: "a"},
    {s: "a", t: "aa"},
];

input_arr.forEach((ele) => {
    console.log(minWindow(ele.s, ele.t));
});